home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / rexx / 241 < prev    next >
Encoding:
Internet Message Format  |  1996-08-06  |  8.8 KB

  1. Path: ix.netcom.com!netnews
  2. From: berniegs@ix.netcom.com(Bernie Schneider)
  3. Newsgroups: comp.lang.rexx,bit.listserv.tsorexx,bit.listserv.ibm-main
  4. Subject: Re: Formatting in REXX
  5. Date: 12 Jan 1996 21:36:40 GMT
  6. Organization: Netcom
  7. Distribution: inet
  8. Message-ID: <4d6k98$4p4@ixnews2.ix.netcom.com>
  9. References: <4d205n$qk0@preeda.internex.net.au>
  10. NNTP-Posting-Host: ix-den11-26.ix.netcom.com
  11. X-NETCOM-Date: Fri Jan 12  1:36:40 PM PST 1996
  12.  
  13. In <4d205n$qk0@preeda.internex.net.au> srinivas@connexus.apana.org.au
  14. (Srinivas Kopparapu) writes: 
  15. >
  16. >Organization: connexus.apana.org.au
  17. >Summary: 
  18. >Keywords: 
  19. >
  20. >Hello everyone, 
  21. >I am using MVS/REXX (IBM) and want to know whether there is
  22. >an easy way for formatting texts/numbers. I read sequential
  23. >datasets/files and want to produce reports with columns and headers
  24. >aligned properly. Basically I want to specify how many characters
  25. >a particular variable should be taking in the report appropriately
  26. >padded with blanks.
  27. >
  28. >At present  I am doing this using LENGTH and COPIES functions. But
  29. >the expression becomes cumbersome if many variables needs to be
  30. >in the same line.
  31. >
  32. >I would appreciate any ideas/tips or pointers in the right direction.
  33. >
  34. >TIA
  35. >Sri
  36. >
  37.  
  38. I find the subroutine below to be convenient. It will format multiple
  39. values into a line. Hope it helps.
  40.  
  41. -------------------------------CUT HERE--------------------------------
  42. /*=====================================================================
  43. */
  44. /* Program: SPRINTF.REX                                                
  45. */
  46. /* Purpose: Returns a string formatted according to the format string  
  47. */
  48. /*          specified in the first argument and the values specified in
  49. */
  50. /*          the remaining arguments. It is modeled after the SPRINTF   
  51. */
  52. /*          function in the C/C++, AWK, PERL, etc. programming         
  53. */
  54. /*          languages.                                                 
  55. */
  56. /* Usage:   say sprintf(fmt_string, value1, value2, ..., valuen)       
  57. */
  58. /*            where fmt_string specifies the formatting to be done on  
  59. */
  60. /*                             the remaining arguments. The string is  
  61. */
  62. /*                             composed of literals and format         
  63. */
  64. /*                             specifiers. There should be one format  
  65. */
  66. /*                             specifier for each value to be
  67. formatted.*/
  68. /*                             Literals are considered to be anything  
  69. */
  70. /*                             that isn't a format specifier. Format    */
  71. /*                             specifiers are coded as follows:         */
  72. /*                                %[-][w][.d]z                          */
  73. /*            where "%" indicates the start of a format specifier. To   */
  74. /*                      use a % in a literal, specify two concecutive   */
  75. /*                      %s (%%, no argument value will be consumed).    */
  76. /*                  "-" is optional, and indicates that the argument    */
  77. /*                      value is to be left justified in its field. If  */
  78. /*                      it isn't present, the value will be right       */
  79. /*                      justified.                                      */
  80. /*                  "w" is optional, and it specifies the width of the  */
  81. /*                      field in characters. If it isn't specified, then*/
  82. /*                      as many characters as necessary will be used.   */
  83. /*                      For decimal numbers, this will depend on the    */
  84. /*                      current value of the numeric digits setting.    */
  85. /*                      The value will be truncated or padded with      */
  86. /*                      blanks as necessary to fit the width specified. */
  87. /*                      Numbers to the right of the decimal point are   */
  88. /*                      padded with "0"s, and will be rounded if        */
  89. /*                      truncation is necessary. If a numeric value is  */
  90. /*                      -1 < valuen < +1, it will be padded with        */
  91. /*                      leading "0"s.                                   */
  92. /*                 ".d" is optional, and it specifies the maximum string*/
  93. /*                      width, or the number of digits to the right of  */
  94. /*                      the decimal point.                              */
  95. /*                  "z" is a single character that indicates the type of*/
  96. /*                      conversion to be performed on the corresponding */
  97. /*                      argument value. It may be one of the following: */
  98. /*                      "d", formats a signed decimal integer           */
  99. /*                      "f", formats a signed decimal real number       */
  100. /*                      "s", formats a character string                 */
  101. /*                      "x", formats an unsigned hexadecimal number     */
  102. /*        Examples:                                                     */
  103. /*          say sprintf("Number = %d", 25)  /* "Number = 25" */         */
  104. /*          say sprintf("Number = %5d", 25) /* "Number =    25" */      */
  105. /*          say sprintf("String = %s", "March") /* "String = March" */  */
  106. /*          say sprintf("String = %5.3s", "March") /* "String =   Mar"*/*/
  107. /*          say sprintf("Num = %8.2f", -123.456) /* "Num =  -123.46" */ */
  108. /*          say sprintf("Num = '%-4x'  String = '%-10s'", ,             */
  109. /*                255, ,                                                */
  110. /*                "AbCde") /* "Num = 'FF  '  String = 'AbCde     '" */  */
  111. /*          say sprintf("%5.1f%%", .1757 * 100)         /* " 17.6%" */  */
  112. /*          say sprintf("Num = %7.3f", 0.25)     /* "Num = 000.250" */  */
  113. /*                                                                      */
  114. /* Written: 27Nov95                                                     */
  115. /* Language:REXX                                                        */
  116. /* Author:  Bernie Schneider                                            */
  117. /* Notes:                                                               */
  118. /* Revised:                                                             */
  119. /*======================================================================*/
  120. /*                                                                      */
  121. sprintf: procedure
  122.   argno = 1                              /* Initialize argument counter */
  123.   string = ''
  124.   start = 1                              /* Initialize pointer */
  125.   len = length(arg(1))
  126.   do until(p >= len)
  127.     s = ''
  128.     argno = argno + 1
  129.     p = pos('%', arg(1), start)
  130.     if p = 0 then do
  131.       p = len + 1
  132.     end
  133.     if substr(arg(1), p, 1) == '%' then do
  134.       s = '%'
  135.     end
  136.     string = string || substr(arg(1), start, p - start)
  137.     start = p + 1
  138.     p = verify(arg(1), '%cdfsx', 'M', start)
  139.     if p = 0 then leave
  140.     spec = substr(arg(1), start, p - start + 1)
  141.     start = p + 1
  142.     r = right(spec, 1)
  143.     spec = delstr(spec, length(spec), 1)
  144.     if left(spec,1) == '-' then do       /* Get any additional specs */
  145.       left = 1
  146.       spec = substr(spec, 2)
  147.     end
  148.     else do
  149.       left = 0
  150.       spec = substr(spec, 1)
  151.     end
  152.     if spec \== '' then                  /* Get width and precision */
  153.       parse var spec width '.' prec
  154.     else do
  155.       width = 0
  156.       prec = 0
  157.     end
  158.     if \datatype(width, 'W') then width = 0
  159.     if \datatype(prec, 'W') then prec = 0
  160.     pad = ' '
  161.     select
  162.       when r == 's' then do
  163.         if width = 0 then width = length(arg(argno))
  164.         if prec \= 0 then s = left(arg(argno), prec) /* Truncate or pad */
  165.         else s = arg(argno)
  166.       end
  167.       when r == 'd' then do
  168.         if width = 0 then width = length(arg(argno))
  169.         s = format(arg(argno), length(arg(argno)), 0)
  170.       end
  171.       when r == 'f' then do
  172.         if arg(argno) > -1 & arg(argno) < 1 then pad = '0'
  173.         parse value arg(argno) with int '.' frac
  174.         if width = 0 & prec = 0 then do
  175.           d = 1
  176.           if arg(argno) < 0 then d = 2
  177.           width = digits() + d
  178.           prec = digits() - (length(int)) + d - 1
  179.         end
  180.         if width = 0 then width = len - prec
  181.         s = format(arg(argno), width, prec)
  182.       end
  183.       when r == 'x' then do
  184.         if width = 0 then width = length(arg(argno))
  185.         s = d2x(arg(argno))
  186.         if prec \= 0 then s = left(s, prec) /* Truncate or pad */
  187.       end
  188.       when r == '%' then do
  189.         argno = argno - 1
  190.       end
  191.     otherwise
  192.       nop
  193.     end
  194.     if r \== '%' then do
  195.       if left then
  196.         s = left(strip(s), width, pad)        /* Justify */
  197.       else
  198.         s = right(strip(s), width, pad)
  199.     end
  200.     string = string || s
  201.   end
  202. return string
  203. -------------------------------CUT HERE--------------------------------
  204. -- 
  205. ------------------------------------------------------------
  206. Bernie Schneider:        | The villain who twirls his
  207.                          | mustache is easy to spot. Those
  208.   berniegs@ix.netcom.com | who cloak themselves in good
  209.   hrrd66a@prodigy.com    | deeds are well camouflaged.
  210.                          |             Capt. Jean Luc Picard
  211.